// Copyright (c) 2023 CHANGLEI. All rights reserved.

import 'package:arith/src/arith.dart';

const _lower = -1.0e100;
const _upper = 1.0e100;
const _epsilon = 1e-8;

/// Created by changlei on 2023/8/3.
///
/// 等式
num _solve({
  num lower = _lower,
  num upper = _upper,
  num epsilon = _epsilon,
  required num Function(num x) f,
}) {
  final x = (lower + upper) / 2.0;
  final result = f(x);
  if (result.abs() < epsilon) {
    return x;
  } else {
    return solve(
      lower: result > 0 ? lower : x,
      upper: result > 0 ? x : upper,
      epsilon: epsilon,
      f: f,
    );
  }
}

/// 解方程
num solve({
  num lower = _lower,
  num upper = _upper,
  num epsilon = _epsilon,
  required num Function(num x) f,
}) {
  return _solve(
    lower: lower,
    upper: upper,
    epsilon: epsilon,
    f: f,
  );
}

/// 扩展
extension ExpressionSolve on Expression {
  /// 解方程
  num solve({
    required String symbol,
    num lower = _lower,
    num upper = _upper,
    num epsilon = _epsilon,
    Map<String, ValueGetter<num>>? variables,
  }) {
    final newVariables = <String, ValueGetter<num>>{
      ...?variables,
    };
    return _solve(
      lower: lower,
      upper: upper,
      epsilon: epsilon,
      f: (x) {
        newVariables[symbol] = () => x;
        return call(newVariables);
      },
    );
  }
}
